package com.jjty.dataGenerator.jshjy.controller;

import com.fasterxml.jackson.databind.ObjectMapper;
import com.jjty.dataGenerator.akq.entity.ResponseResult;
import com.jjty.dataGenerator.jshjy.entity.*;
import com.jjty.dataGenerator.jshjy.service.JsDataService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import java.lang.reflect.Field;
import java.util.HashSet;
import java.util.Iterator;
import java.util.Set;

@RestController
@RequestMapping("/openapi/stu-card/sync")
public class DataSyncController {

    @Autowired
    private ObjectMapper objectMapper;
    @Autowired
    private JsDataService dataService;

    /**
     * 接口1：心跳数据推送
     */
    @PostMapping("/heartbeat")
    public ResponseResult<Void> syncHeartbeat(@RequestBody String requestBody) {
        try {
            // 校验请求参数是否合法
            if (!validateRequestBody(requestBody, JsHeartbeatData.class)) {
                return ResponseResult.fail("请求参数包含非法字段");
            }
            JsHeartbeatData data = objectMapper.readValue(requestBody, JsHeartbeatData.class);
            dataService.saveHeartbeatData(data);
            return ResponseResult.success();
        } catch (Exception e) {
            return ResponseResult.fail("心跳数据推送失败：" + e.getMessage());
        }
    }

    /**
     * 接口2：定位数据推送
     */
    @PostMapping("/location")
    public ResponseResult<Void> syncLocation(@RequestBody String requestBody) {
        try {
            if (!validateRequestBody(requestBody, JsLocationData.class)) {
                return ResponseResult.fail("请求参数包含非法字段");
            }
            JsLocationData data = objectMapper.readValue(requestBody, JsLocationData.class);
            dataService.saveLocationData(data);
            return ResponseResult.success();
        } catch (Exception e) {
            return ResponseResult.fail("定位数据推送失败：" + e.getMessage());
        }
    }

    /**
     * 接口3：通话数据推送
     */
    @PostMapping("/call")
    public ResponseResult<Void> syncCall(@RequestBody String requestBody) {
        try {
            if (!validateRequestBody(requestBody, JsCallData.class)) {
                return ResponseResult.fail("请求参数包含非法字段");
            }
            JsCallData data = objectMapper.readValue(requestBody, JsCallData.class);
            dataService.saveCallData(data);
            return ResponseResult.success();
        } catch (Exception e) {
            return ResponseResult.fail("通话数据推送失败：" + e.getMessage());
        }
    }

    /**
     * 接口4：考勤数据推送
     */
    @PostMapping("/attendance")
    public ResponseResult<Void> syncAttendance(@RequestBody String requestBody) {
        try {
            if (!validateRequestBody(requestBody, JsAttendanceData.class)) {
                return ResponseResult.fail("请求参数包含非法字段");
            }
            JsAttendanceData data = objectMapper.readValue(requestBody, JsAttendanceData.class);
            dataService.saveAttendanceData(data);
            return ResponseResult.success();
        } catch (Exception e) {
            return ResponseResult.fail("考勤数据推送失败：" + e.getMessage());
        }
    }

    /**
     * 接口5：基础数据推送
     */
    @PostMapping("/base")
    public ResponseResult<Void> syncBase(@RequestBody String requestBody) {
        try {
            if (!validateRequestBody(requestBody, JsBaseData.class)) {
                return ResponseResult.fail("请求参数包含非法字段");
            }
            JsBaseData data = objectMapper.readValue(requestBody, JsBaseData.class);
            dataService.saveBaseData(data);
            return ResponseResult.success();
        } catch (Exception e) {
            return ResponseResult.fail("基础数据推送失败：" + e.getMessage());
        }
    }

    /**
     * 校验请求体是否包含实体类中未定义的字段
     */
    private boolean validateRequestBody(String requestBody, Class<?> entityClass) throws Exception {
        com.fasterxml.jackson.databind.node.ObjectNode jsonNode = 
            objectMapper.readTree(requestBody).deepCopy();
        Set<String> fieldNames = getEntityFieldNames(entityClass);
        
        // 遍历请求体中的所有字段，检查是否存在实体类中未定义的字段
        for (Iterator<String> it = jsonNode.fieldNames(); it.hasNext(); ) {
            String field = it.next();
            if (!fieldNames.contains(field)) {
                return false;
            }
        }
        return true;
    }

    /**
     * 获取实体类中所有的字段名（用于参数校验）
     */
    private Set<String> getEntityFieldNames(Class<?> entityClass) {
        Set<String> fieldNames = new HashSet<>();
        Field[] fields = entityClass.getDeclaredFields();
        for (Field field : fields) {
            fieldNames.add(field.getName());
        }
        return fieldNames;
    }
}